/*============================================================================*/
/*  Copyright (C) 2009-2011, iSOFT INFRASTRUCTURE SOFTWARE CO.,LTD.
 *  
 *  All rights reserved. This software is iSOFT property. Duplication 
 *  or disclosure without iSOFT written authorization is prohibited.
 *  
 *  @file       <Xcp_Interface.c>
 *  @brief      <Xcp Module Interface Code file. This version is compitable with CANape.>
 *  
 *  <Compiler: Codewarrior for mpc55xx v2.6     MCU:MPC56XX>
 *  
 *  @author     <Dongyuan.Sun, qitao.Yu>
 *  @date       <2013-03-06>
 */
/*============================================================================*/

/*=======[R E V I S I O N   H I S T O R Y]====================================*/
/*  <VERSION>    <DATE>    <AUTHOR>         <REVISION LOG>
 *  V1.0.0       20130306  Dongyuan.Sun     Initial version
 * 
 */
/*============================================================================*/

/*=======[I N C L U D E S]====================================================*/
#include "Xcp_Interface.h"
#include "Fls.h"

/*=======[I N T E R N A L   F U N C T I O N   D E C L A R A T I O N S]========*/

STATIC uint16 XcpCrc16Ccitt(const uint8* pu1data, uint16 u2Crc);



#if (XCP_PL_STIM == (XCP_PL_STIM & XCP_RESOURCE))
boolean Xcp_StimOverloadIndication(uint16 eventNum, uint16 daqNum)
{
    return TRUE;
}
#endif


/*==========================================================================*/

/*
	FUNCTION NAME:		CcpCrc16Ccitt
	COMPONENT:			CAN Calibration Protocol
	SCOPE:				<APPLICATION/COMPONENT/PACKAGE>
	DESCRIPTION:
		<This function is used when computing the crc16>
*/
/*==========================================================================*/
STATIC uint16 XcpCrc16Ccitt(const uint8* pu1data, uint16 u2Crc)
{
	uint8 CrCCounter;
	uint16 t_u2_ccitt16 = (uint16)0x1021u;
	u2Crc ^= ((uint16)(*pu1data) << 8u);
	for (CrCCounter = 0; CrCCounter < 8; CrCCounter++)
	{
		if ((u2Crc & (uint16)0x8000u) == (uint16)0x8000u)
		{
			u2Crc <<= 1;
			u2Crc ^= t_u2_ccitt16;
		}
		else
		{
			u2Crc <<= 1;
		}
	}
	return u2Crc;
}

/*==========================================================================*/

/*
	FUNCTION NAME:		Ccp_CRC16Compute
	COMPONENT:			CAN Calibration Protocol
	SCOPE:				<APPLICATION/COMPONENT/PACKAGE>
	DESCRIPTION:
		<This function is used to build checksum in Ccp.c and return the size of the checksum >
*/
/*==========================================================================*/
FUNC(void, XCP_CODE) Xcp_ChecksumCompute(const uint32 checksumStartAddress, const uint32 blockSize, uint32* crcResult)
{
	uint32 i;
	uint16 t_u2Result;
	t_u2Result = (uint16)0xffffu;
	
	for (i = 0; i < blockSize; i++)
	{
		t_u2Result = XcpCrc16Ccitt((uint8 *)(checksumStartAddress + i), t_u2Result);
	}   
    *crcResult = (uint32)t_u2Result;
    
	return ;
}

/* FUNC(uint32, XCP_CODE) */
uint32 Xcp_Mta2Ptr(const uint8 u1AddExt, const uint32 u4Add)
{
    return u4Add;
}

Std_ReturnType Xcp_CreateSeed(uint8* length, uint8* seed, const uint8 resource)
{
    uint8 i;
    *length = resource;
    for (i = 0; i < *length; i++)
    {
        seed[i] = i;
    }
    
    return E_OK;
}

boolean Xcp_IsKeyRight(const uint8* seed, const uint8* key, const uint8 lengthS,const uint8 lengthK, const uint8 resource)
{
    uint8 i = 0;
    if ((lengthK == resource)
    && (lengthS == resource))
    {
        for (i = 0; i < lengthK; i++)
        {
            if (key[i] != (seed[i] + seed[i/2]))
            {
                break;
            }
        }
        if (resource != i)
        {
            return FALSE;
        }
        else
        {
            return TRUE;
        }
    }
    else
    {
        return FALSE;
    }
}


/* FUNC(uint8, XCP_CODE) */
uint8 Xcp_FlsGetStatus(void)
{
    uint8 result;
    MemIf_JobResultType jobResult = Fls_GetJobResult();
    switch(jobResult)
    {
        case MEMIF_JOB_PENDING:
            result = XCP_IF_BUSY;
            break;
        case MEMIF_JOB_OK:
            result = XCP_IF_OK;
            break;
        default:
            result = XCP_IF_NOT_OK;
            break;
    }
    return result;
}

/******************************************************************************/
/*
 * @brief               <BRIEF DESCRIPTION>
 *
 * <DETAILED DESCRIPTION> .
 * Service ID   :       <SERVICE ID>
 * Sync/Async   :       <Synchronous/Asynchronous>
 * Reentrancy           <Reentrant/Non Reentrant>
 * @param[in]           <PARAMETER1 (IN), PARAMETER2 (IN)>
 * @param[out]          <PARAMETER1 (OUT), PARAMETER2 (OUT)>
 * @param[in/out]       <PARAMETER1 (IN/OUT), PARAMETER2 (IN/OUT)>
 * @return              <RETURN VALUE>
 */
/******************************************************************************/
extern Std_ReturnType Xcp_FlsReq(uint8 Mode, uint32 u4Address, uint32 u4Size, const uint8* pu1DataPtr)
{
	uint8 index;
	P2CONST(Fls_SectorType, AUTOMATIC, FLS_APPL_DATA) sectorPtr = NULL_PTR;
	/*Modified start, by li.zhu, 2015/10/23,*/
	/* Only for TC1782, because the address is different from the address of Flash. */
    u4Address &= 0xFFFFFFF;
	/*Modified end, by li.zhu, 2015/10/23,*/
	switch(Mode)
	{
		case XCP_FLS_WRITE:
			for(index = 0; index < FLS_BLOCK_NUMBER; index++)
			{
				sectorPtr = FLS_SECTOR_PTR(index);
				if ((u4Address >= sectorPtr->FlsSectorStartaddress) && (u4Address <= sectorPtr->FlsSectorEndaddress))
				{
					if (0u == (u4Address & (sectorPtr->FlsPageSize - 1u)))
					{
						return Fls_Write(u4Address, pu1DataPtr, u4Size);
					}
				}
			}
			break;

		case XCP_FLS_ERASE:
			for(index = 0; index < FLS_BLOCK_NUMBER; index++)
			{
				sectorPtr = FLS_SECTOR_PTR(index);
				if ((u4Address >= sectorPtr->FlsSectorStartaddress) && (u4Address <= sectorPtr->FlsSectorEndaddress))
				{
					return Fls_Erase(u4Address , u4Size);
				}
			}
			break;

		default:
			/* Do nothing */
			break;
	}
    return E_NOT_OK;
}


/******************************************************************************/
/*
 * @brief               <BRIEF DESCRIPTION>
 * 
 * <DETAILED DESCRIPTION> .
 * Service ID   :       <SERVICE ID>
 * Sync/Async   :       <Synchronous/Asynchronous>
 * Reentrancy           <Reentrant/Non Reentrant>
 * @param[in]           <PARAMETER1 (IN), PARAMETER2 (IN)>
 * @param[out]          <PARAMETER1 (OUT), PARAMETER2 (OUT)>
 * @param[in/out]       <PARAMETER1 (IN/OUT), PARAMETER2 (IN/OUT)>
 * @return              <RETURN VALUE>    
 */
/******************************************************************************/
extern void Xcp_FlsMainFunction(void)
{
    /*Fls_MainFunction();*/
    return;
}


/******************************************************************************/
/*
 * @brief               <BRIEF DESCRIPTION>
 * 
 * <DETAILED DESCRIPTION> .
 * Service ID   :       <SERVICE ID>
 * Sync/Async   :       <Synchronous/Asynchronous>
 * Reentrancy           <Reentrant/Non Reentrant>
 * @param[in]           <PARAMETER1 (IN), PARAMETER2 (IN)>
 * @param[out]          <PARAMETER1 (OUT), PARAMETER2 (OUT)>
 * @param[in/out]       <PARAMETER1 (IN/OUT), PARAMETER2 (IN/OUT)>
 * @return              <RETURN VALUE>    
 */
/******************************************************************************/
extern Std_ReturnType Xcp_ProgramStartNoticeApp(void)
{
    return E_OK;
}


/******************************************************************************/
/*
 * @brief               <BRIEF DESCRIPTION>
 * 
 * <DETAILED DESCRIPTION> .
 * Service ID   :       <SERVICE ID>
 * Sync/Async   :       <Synchronous/Asynchronous>
 * Reentrancy           <Reentrant/Non Reentrant>
 * @param[in]           <PARAMETER1 (IN), PARAMETER2 (IN)>
 * @param[out]          <PARAMETER1 (OUT), PARAMETER2 (OUT)>
 * @param[in/out]       <PARAMETER1 (IN/OUT), PARAMETER2 (IN/OUT)>
 * @return              <RETURN VALUE>    
 */
/******************************************************************************/
extern void Xcp_ProgramResetNoticeApp(void)
{
    return;
}

/*=======[E N D   O F   F I L E]==============================================*/

